<template>
  <div class="wrapper">
      <div class="grid-content ep-bg-purple-light">
        <el-row type="flex" justify="center">
          <el-col :span="14">
            <el-form :inline="true">
              <el-form-item label="Language">
                <el-select v-model="language" placeholder="选择语言" @change="handleLanguage">
                  <el-option
                      v-for="(languageItem, key) in languageOptions"
                      :key="key"
                      :label="languageItem"
                      :value="languageItem">
                  </el-option>
                </el-select>
              </el-form-item>
              <el-form-item label="Theme">
                <el-select v-model="editorTheme" placeholder="设置主题" @change="handleTheme">
                  <el-option label="Visual Studio Dark" value="vs-dark"></el-option>
                  <el-option label="Visual Studio" value="vs"></el-option>
                  <el-option label="High Contrast Dark" value="hc-black"></el-option>
                </el-select>
              </el-form-item>
            </el-form>
            <div id="codeEditBox"></div>
            <el-button @click="handleCode" v-if="!this.$props.readFlag">点击运行</el-button>
            <el-button @click="handleFormat" type="primary" v-if="language == 'json' || language == 'sql'">格式化</el-button>
          </el-col>
          <el-col :span="10">
            <el-card class="resultBox" shadow="always">
              <template #header>
                <div class="resultTitle">
                  <span>
                    运行结果 {{result.status}}
                  </span>
                </div>
              </template>
              <div class="result" v-if="result.status=='Compile Error'">
                   {{'编译错误： ' + result.testcase[0].stderr}}
              </div>
              <div class="result" v-for="o in result.testcase" :key="o" v-else>
                <div>
                  {{'测试用例：' + o.test}}
                </div>
                <div>
                  {{'用例结果：' + o.testresult}}
                </div>
                <div>
                  {{'消耗时间：' + o.time}}
                </div>
                <div>
                  {{'消耗内存：' + o.memory}}
                </div>
              </div>
            </el-card>
          </el-col>
        </el-row>
      </div>
  </div>
</template>
<script>


import api from "../api/api.js";
import * as monaco from 'monaco-editor';
import { ref, toRaw } from 'vue';
import $ from 'jquery';
import { format } from 'sql-formatter';
import { pythonCompletion, sqlCompletion, cppCompletion, javaCompletion,
  csharpCompletion } from "@/utils/completion";
import { useRoute } from 'vue-router'

export default {
  name: "MonacoEditor",
  props: {
    pid: {
      required: true
    },
    cid: {
      required: false, // 标记是否从比赛页面跳转过来的题目,如果是的话后续传参需要插入到比赛的Status
      default: '-1'
    },
    readFlag: {
      required: false,
      default: false
    },
    codeValue: {
      required: false,
      default: ""
    }
  },
  setup(props) {
    const editor = ref(null)
    const result = ref({
        status: "",
        testcase: []
    })
    const editorTheme = ref("vs-dark")
    const language = ref("cpp")
    /*const languageOptions = ref(["bat", "cpp", "csharp", "css", "dockerfile", "go", "graphql", "html", "ini",
      "java", "javascript", "json", "julia", "kotlin", "less", "markdown", "mysql", "objective-c", "pascal", "pascaligo",
      "perl", "php", "powershell", "python", "r", "redis", "rust", "scala", "scheme", "scss", "shell",
      "sophia", "sql", "swift", "tcl", "typescript", "xml", "yaml"])*/
    const languageOptions = ref(["cpp", "java", "javascript"])
    const initEditor = () => {
      // 初始化编辑器，确保dom已经渲染
      editor.value = monaco.editor.create(document.getElementById('codeEditBox'), {
        value: props.codeValue, //编辑器初始显示文字
        language: language.value, //语言支持自行查阅demo
        theme: editorTheme.value, //官方自带三种主题vs, hc-black, or vs-dark
        selectOnLineNumbers: true,//显示行号
        roundedSelection: false,
        readOnly: props.readFlag, // 只读
        cursorStyle: 'line', //光标样式
        automaticLayout: true, //自动布局
        glyphMargin: true, //字形边缘
        useTabStops: false,
        fontSize: 15, //字体大小
        autoIndent: true, //自动布局
        quickSuggestionsDelay: 100, //代码提示延时
      });

      // 监听值的变化
      // editor.value.onDidChangeModelContent((val) => {
      //   console.log(val.changes[0].text)
      // })

      // 创建代码提醒
      pythonCompletion
      sqlCompletion
      cppCompletion
      csharpCompletion
      javaCompletion
    }
    $(document).ready(function () {
      initEditor()
    })
    const handleCode = () => {
      // 在这里提交pid 和 cid 及 code
      let formData = new FormData()
      formData.append("code", toRaw(editor.value).getValue())
      formData.append("pid", props.pid)
      formData.append("cid", props.cid)
      formData.append("uid", localStorage.getItem("uid"))
      api.
        RunProblemCode(formData).
        then((res) => {
          console.log(res.data);
          for (var i = 0; i < res.data.length; i++)
          {
              if (res.data[i].status) // 最终的测试结果
              {
                  result.value.status = res.data[i].status;
              }
          }
          console.log(result.value.status);
          for (var i = 0; i < res.data.length; i++)
          {
              if (result.value.status == 'Accept')
              {
                result.value.testcase.push(
                    {
                      test: res.data[i].test,
                      testresult: res.data[i].testresult,
                      time: res.data[i].time,
                      memory: res.data[i].memory
                    }
                );
              }
              else if (result.value.status == 'Compile Error')
              {
                  result.value.testcase.push({
                     stderr: res.data[i].stderr
                  })
                  break;
              }
          }

        })
    }
    const handleTheme = () => {
      monaco.editor.setTheme(editorTheme.value)
    }
    const handleLanguage = (item) => {
      language.value = item
      monaco.editor.setModelLanguage(toRaw(editor.value).getModel(), language.value)
      // console.log(toRaw(editor.value).getModel().getLanguageId())
    }
    const handleFormat = () => {
      let lan = toRaw(editor.value).getModel().getLanguageId()
      console.log(lan)
      let content = toRaw(editor.value).getValue()
      if (lan == 'sql'){
        toRaw(editor.value).setValue(format(content))
      }
      else if (lan == 'json') {
        toRaw(editor.value).trigger('anyString', 'editor.action.formatDocument')
        toRaw(editor.value).setValue(content)
      }
    }
    return {
      editor,
      handleCode,
      result,
      handleTheme,
      editorTheme,
      language,
      handleLanguage,
      languageOptions,
      handleFormat
    }
  }

}
</script>

<style scoped>

.wrapper {
  margin: 20px auto;
}
#codeEditBox {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  height: 650px;
  padding: 0;
  overflow: hidden;
  margin-bottom: 15px;
}
.resultBox {
  margin-top: 0px;
  height: 800px;
  overflow-y: scroll;
}
.resultBox .resultTitle {
  color: #409EFF ;
}
.resultBox .result {
  font-size: 16px;
  color: #969696;
  margin-bottom: 20px;
  text-align: left;
}
</style>
